home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / oper_sys / oasis / oasis1-1.lha / oasis-1.1 / print.c < prev    next >
C/C++ Source or Header  |  1992-05-01  |  27KB  |  811 lines

  1. /*==========================================================================*
  2.     Oasis Alpha Version 1.1               (C) Copyright 1992 Fah-Chun Cheong
  3.     Revised: 5/1/92 by: fcc@eecs.umich.edu    and The University of Michigan
  4.     ------------------------------------------------------------------------
  5.     Permission to use, copy, modify, distribute, sell and resell Oasis Alpha
  6.     software and its documentation for any purpose and without fee is hereby
  7.     granted, provided that the authorship be appropriately credited and
  8.     acknowledged, and that the above copyright notice appear in all copies
  9.     and both the copyright notice and this permission notice appear in
  10.     supporting documentation. The author makes no representations about the
  11.     suitability of this software for any purpose. It is provided "as is"
  12.     without express or implied warranty. Oasis Alpha is free, caveat emptor!
  13.     ------------------------------------------------------------------------
  14.     To request Oasis Alpha source code:   oasis-alpha-request@eecs.umich.edu
  15.     To enroll in the mailing list:        oasis-alpha-request@eecs.umich.edu
  16.     To send bug reports:                  oasis-alpha-bugs@eecs.umich.edu
  17.     To discuss openly all matters Oasis:  oasis-alpha@eecs.umich.edu
  18.  *==========================================================================*/
  19. #include                "parser.h"
  20. #include                "par.h"
  21.  
  22. #define print0(s)       ptr += strlen((sprintf(ptr, s),       ptr))
  23. #define print1(s,a)     ptr += strlen((sprintf(ptr, s, a),    ptr))
  24. #define print2(s,a,b)   ptr += strlen((sprintf(ptr, s, a, b), ptr))
  25.  
  26. static  char           *ptr;
  27.  
  28. int     len_props(props)
  29. Prop   *props;
  30. {
  31.         int     i = 0;
  32.  
  33.         for (; props; props = props->next) i++;
  34.         return i;
  35. }
  36.  
  37. int     len_pars(pars, flow)
  38. Par    *pars;
  39. int     flow;
  40. {
  41.         int     i = 0;
  42.  
  43.         for (; pars; pars = pars->next)
  44.             if (pars->flow == flow) i++;
  45.         return i;
  46. }
  47.  
  48. Par    *next_pars(pars, flow)
  49. Par    *pars;
  50. int     flow;
  51. {
  52.         for (; pars; pars = pars->next)
  53.             if (pars->flow == flow) break;
  54.         return pars;
  55. }
  56.  
  57. int     match_pars(pars1, pars2)
  58. Par    *pars1;
  59. Par    *pars2;
  60. {
  61.         if (len_pars(pars1, IN) != len_pars(pars2, IN))
  62.             return FALSE;
  63.  
  64.         pars1 = next_pars(pars1, OUT);
  65.         pars2 = next_pars(pars2, OUT);
  66.         while (pars1 && pars2) {
  67.             if (pars1->node->tag  != VAR  ||
  68.                 pars2->node->tag  != LVAR ||
  69.                 Voff(pars1->node) != Voff(pars2->node))
  70.                 return FALSE;
  71.             pars1 = next_pars(pars1->next, OUT);
  72.             pars2 = next_pars(pars2->next, OUT);
  73.         }
  74.         return (pars1 || pars2) ? FALSE : TRUE;
  75. }
  76.  
  77. int     max_vars(rules, moff)
  78. Rule   *rules;
  79. int     moff;
  80. {
  81.         int     max = 1;
  82.  
  83.         while (rules && rules->head->moff == moff) {
  84.             Par *pars = rules->head->pars;
  85.             Var *vars = rules->vars;
  86.             int  k    = 0;
  87.             int  s    = 1;
  88.  
  89.             for (; pars; pars = pars->next)
  90.                 if (pars->node->tag == LVAR) {
  91.                     if (!islast(rules, moff))
  92.                         ((Var *) pars->node->this.p)->use = LAST;
  93.                     Voff(pars->node) = ++k;
  94.                     pars->node = Anon;
  95.                 }
  96.                 else if (pars->flow == IN) {
  97.                     Type *type = pars->node->type;
  98.                     vars = Var_("_", ++k, BB, HEAD, HEAD, type, type, type, vars);
  99.                     if (!islast(rules, moff))
  100.                         vars->use = LAST;
  101.                 }
  102.  
  103.             for (; vars; vars = vars->next)
  104.                 if (vars->voff == 0)
  105.                     vars->voff = -++s;
  106.  
  107.             max = s > max ? s : max;
  108.             rules = rules->next;
  109.         }
  110.         return max - 1;
  111. }
  112.  
  113. int     in_node(node)
  114. Node   *node;
  115. {
  116.         if (node) switch (node->tag) {
  117.             case ARRAY:
  118.             case HANDLE:
  119.             case AT:
  120.             case OBJECT:
  121.             case STRING:    return TRUE;
  122.             case LIST:      if (node->this.p)
  123.                                 return TRUE;
  124.         }
  125.         return FALSE;
  126. }
  127.  
  128. int     in_pars(pars, flow)
  129. Par    *pars;
  130. int     flow;
  131. {
  132.         for (; pars; pars = pars->next)
  133.             if (pars->flow == flow &&
  134.                 in_node(pars->node))
  135.                 return TRUE;
  136.         return FALSE;
  137. }
  138.  
  139. int     in_preds(preds)
  140. Pred   *preds;
  141. {
  142.         for (; preds; preds = preds->next)
  143.             switch (preds->tag) {
  144.                 case SEND:  if (in_node(preds->dest))       return TRUE;
  145.                 case INVK:
  146.                 case CALL:
  147.                 case WAIT:
  148.                 case POST:  if (in_pars(preds->pars, IN))   return TRUE; break;
  149.                 case RELOP: if (in_node(preds->pars))       return TRUE; break;
  150.             }
  151.         return FALSE;
  152. }
  153.  
  154. int     in_clus(clus)
  155. Clu    *clus;
  156. {
  157.         for (; clus; clus = clus->next)
  158.             if (in_preds(clus->pred))
  159.                 return TRUE;
  160.         return FALSE;
  161. }
  162.  
  163. int     in_rules(rules, moff)
  164. Rule   *rules;
  165. int     moff;
  166. {
  167.         while (rules && rules->head->moff == moff) {
  168.             if (in_clus (rules->body) ||
  169.                 in_clus (rules->tail) ||
  170.                 in_preds(rules->last))
  171.                 return TRUE;
  172.             rules = rules->next;
  173.         }
  174.         return FALSE;
  175. }
  176.  
  177. void    print_node(vars, node)
  178. Var    *vars;
  179. Node   *node;
  180. {
  181.         if (node) switch (node->tag) {
  182.             case AS:    print_node(vars,     node->this.p);
  183.                         print_node(vars,     node->that);               break;
  184.             case LIST:  if (node->this.p) {
  185.                             print1("%d",     len_props(node->this.p));
  186.                             print_tag       (get_elem(node->type));
  187.                         }
  188.             case LLIST: print0("[");
  189.                         print_props(vars,    node->this.p);
  190.                         if (node->that) {
  191.                             print0("|");
  192.                             print_node(vars, node->that);
  193.                         }
  194.                         print0("]");                                    break;
  195.             case ARRAY: print_node(vars,     node->this.p);
  196.                         if (node->that) {
  197.                             print0("{");
  198.                             print_node(vars, node->that);
  199.                             print0("}");
  200.                         }                                               break;
  201.             case DOPE:  print1("%d:",        len_props(node->that));
  202.                         print1("%d",         node->this.i);
  203.                         print_tag           (get_item(node->type));
  204.             case LDOPE: print0("$[");
  205.                         print_props(vars,    node->that);
  206.                         print0("]");                                    break;
  207.             case ITEM:  print_node(vars,     node->this.p);
  208.                         if (node->that) {
  209.                             print0(",");
  210.                             print_node(vars, node->that);
  211.                         }                                               break;
  212.             case AT:    print_node(vars,     node->this.p);
  213.                         print_node(vars,     node->that);               break;
  214.             case HANDLE:print1("%s:",        node->type->u.class->name);
  215.                         print1("%d",         node->this.i);
  216.                         print_node(vars,     node->that);               break;
  217.             case AGENT:
  218.             case OBJECT:print1("%s:",        node->type->u.class->name);
  219.                         print1("%d",         node->this.i);
  220.                         if (node->type->u.class->cons) {
  221.                             print0("[");
  222.                             print_tags      (node->type->u.class->cons);
  223.                             print0("]");
  224.                         }
  225.                         print0("{");
  226.                         print_props(vars,    node->that);
  227.                         print0("}");                                    break;
  228.             case SITE:  print1("@%s",        node->this.p);
  229.                         print1(":%d",        node->that);               break;
  230.             case COND:  print1("~%d",        node->this.i);             break;
  231.             case LVAR:  print0("?");
  232.             case VAR:   print1("#%d",        Voff(node));
  233.                         print_node(vars,     node->that);
  234.                         print_tag           (node->type);               break;
  235.             case LREF:  print0("?");
  236.             case REF:   print1("`%d",        node->this.i);
  237.                         print_node(vars,     node->that);
  238.                         print_tag           (node->type);               break;
  239.             case FIELD: print1(".`%d",       node->this.p);
  240.                         print_node(vars,     node->that);               break;
  241.             case INDEX: print0("[");
  242.                         print_props(vars,    node->this.p);
  243.                         print0("]");
  244.                         print_node(vars,     node->that);               break;
  245.             case EXPR:  print0("(");
  246.                         print_node(vars,     node->this.p);
  247.                         print0(")");
  248.                         print_tag           (node->type);               break;
  249.             case FUN:   print1("%s(",        node->this.p);
  250.                         print_node(vars,     node->that);
  251.                         print0(")");                                    break;
  252.             case ADD:
  253.             case SUB:
  254.             case MUL:
  255.             case DIV:
  256.             case REM:   print0("(");
  257.                         print_node(vars,     node->this.p);
  258.                         print1("%c",         node->tag);
  259.                         print_tag           (node->type);
  260.                         print_node(vars,     node->that);
  261.                         print0(")");                                    break;
  262.             case RADD:
  263.             case RMUL:  print0("(");
  264.                         print_node(vars,     node->that);
  265.                         print1("%c",        -node->tag);
  266.                         print_tag           (node->type);
  267.                         print_node(vars,     node->this.p);
  268.                         print0(")");                                    break;
  269.             case RSUB:
  270.             case RDIV:
  271.             case RREM:  print0("(");
  272.                         print_node(vars,     node->that);
  273.                         print1("%c'",       -node->tag);
  274.                         print_tag           (node->type);
  275.                         print_node(vars,     node->this.p);
  276.                         print0(")");                                    break;
  277.             case INT:   print1("%d",         node->this.i);             break;
  278.             case REAL:  print1("%f",         node->this.f);             break;
  279.             case CHAR:  print1("'%s'",       node->this.p);             break;
  280.             case STRING:print1("\"%s\"",     node->this.p);             break;
  281.             case ANON:  print0("_");                                    break;
  282.             case NIL:   print0("$nil");                                 break;
  283.             case SELF:  print0("#0");
  284.                         print_tag           (node->type);               break;
  285.         }
  286. }
  287.  
  288. void    print_tag(type)
  289. Type   *type;
  290. {
  291.         switch (type->tag) {
  292.             case CHAR:  print0(":c");                           break;
  293.             case INT:   print0(":i");                           break;
  294.             case REAL:  print0(":f");                           break;
  295.             case OBJECT:print0(":o");                           break;
  296.             case AGENT: print0(":a");                           break;
  297.             case ARRAY: print0(":y");                           break;
  298.             case LIST:  print0(":l");                           break;
  299.             case META:  print1(":$%d",  type->u.meta);          break;
  300.         }
  301. }
  302.  
  303. void    print_tags(cons)
  304. Con    *cons;
  305. {
  306.         while (cons) {
  307.             print_tag(cons->type);
  308.             cons = cons->next;
  309.             print0(cons ? "," : "");
  310.         }
  311. }
  312.  
  313. void    print_type(type)
  314. Type   *type;
  315. {
  316.         switch (type->tag) {
  317.             case CHAR:  print0("c:");                           break;
  318.             case INT:   print0("i:");                           break;
  319.             case REAL:  print0("f:");                           break;
  320.             case OBJECT:print1("o:%s ", type->u.class->name);
  321.                         print0("[");
  322.                         print_types(type->u.class->cons);
  323.                         print0("]");                            break;
  324.             case AGENT: print1("a:%s ", type->u.class->name);
  325.                         print0("[]");                           break;
  326.             case ARRAY: print0("y:");
  327.                         print_type     (type->u.array->item);
  328.                         print0("[");
  329.                         print_dims     (type->u.array->dims);
  330.                         print0("]");                            break;
  331.             case LIST:  print0("l:");
  332.                         print_type     (type->u.list);          break;
  333.         }
  334. }
  335.  
  336. void    print_types(cons)
  337. Con    *cons;
  338. {
  339.         while (cons) {
  340.             print_type(cons->type);
  341.             cons = cons->next;
  342.             print0(cons ? "," : "");
  343.         }
  344. }
  345.  
  346. void    print_dims(dims)
  347. Dim    *dims;
  348. {
  349.         while (dims) {
  350.             print1("%d", dims->size);
  351.             dims = dims->next;
  352.             print0(dims ? "," : "");
  353.         }
  354. }
  355.  
  356. void    print_props(vars, props)
  357. Var    *vars;
  358. Prop   *props;
  359. {
  360.         while (props) {
  361.             print_node(vars, props->node);
  362.             props = props->next;
  363.             print0(props ? "," : "");
  364.         }
  365. }
  366.  
  367. int     print_rpars(vars, pars, flow)
  368. Var    *vars;
  369. Par    *pars;
  370. int     flow;
  371. {
  372.         for (; pars; pars = pars->next)
  373.             if (pars->flow == flow) {
  374.                 if (print_rpars(vars, pars->next, flow))
  375.                     print0(", ");
  376.                 print_node(vars, pars->node);
  377.                 return TRUE;
  378.             }
  379.         return FALSE;
  380. }
  381.  
  382. void    print_pars(vars, pars, flow)
  383. Var    *vars;
  384. Par    *pars;
  385. int     flow;
  386. {
  387.         for (; pars; pars = pars->next)
  388.             if (pars->flow == flow) {
  389.                 print_node(vars, pars->node);
  390.                 pars = pars->next; break;
  391.             }
  392.         for (; pars; pars = pars->next)
  393.             if (pars->flow == flow) {
  394.                 print0(", ");
  395.                 print_node(vars, pars->node);
  396.             }
  397. }
  398.  
  399. int     print_rargs(pars, flow)
  400. Par    *pars;
  401. int     flow;
  402. {
  403.         for (; pars; pars = pars->next)
  404.             if (pars->flow == flow) {
  405.                 if (print_rargs(pars->next, flow))
  406.                     print0(", ");
  407.                 print_tag(pars->node->type);
  408.                 return TRUE;
  409.             }
  410.         return FALSE;
  411. }
  412.  
  413. void    print_vars(vars, step)
  414. Var    *vars;
  415. int     step;
  416. {
  417.         Var    *vs;
  418.  
  419.         for (vs = vars; vs; vs = vs->next)
  420.             if (ispointer(vs->mint) && islive(vs, step)) {
  421.                 print1("#%d",  vs->voff);
  422.                 print_tag     (vs->mint);
  423.                 vs = vs->next; break;
  424.             }
  425.         for (; vs; vs = vs->next)
  426.             if (ispointer(vs->mint) && islive(vs, step)) {
  427.                 print1(",#%d", vs->voff);
  428.                 print_tag     (vs->mint);
  429.             }
  430.         print0(";");
  431.  
  432.         for (vs = vars; vs; vs = vs->next)
  433.             if (ismeta(vs->mint) && islive(vs, step)) {
  434.                 print1("#%d",  vs->voff);
  435.                 print_tag     (vs->mint);
  436.                 vs = vs->next; break;
  437.             }
  438.         for (; vs; vs = vs->next)
  439.             if (ismeta(vs->mint) && islive(vs, step)) {
  440.                 print1(",#%d", vs->voff);
  441.                 print_tag     (vs->mint);
  442.             }
  443. }
  444.  
  445. void    print_last(vars, last)
  446. Var    *vars;
  447. Pred   *last;
  448. {
  449.         print1("&%d", last->moff);
  450.         print0("(");
  451.         print_rpars(vars, last->pars, IN);
  452.         print0(")");
  453.         if (last->dest)
  454.             print1(" ::%s", last->dest);
  455. }
  456.  
  457. int     print_preds(vars, step, preds, last)
  458. Var    *vars;
  459. int     step;
  460. Pred   *preds;
  461. Pred   *last;
  462. {
  463.         if (preds != last) switch (preds->tag) {
  464.             case FALSE:     print0("$fail");
  465.                             return FALSE;
  466.             case TRUE:      print0("$true");
  467.                             return TRUE;
  468.             case RELOP:     print_node(vars, preds->pars);
  469.                             switch (preds->moff) {
  470.                                 case IS:    print0(" = ");  break;
  471.                                 case EQ:    print0(" == "); break;
  472.                                 case NE:    print0(" <> "); break;
  473.                                 case LT:    print0(" > ");  break;
  474.                                 case LE:    print0(" >= "); break;
  475.                                 case GT:    print0(" < ");  break;
  476.                                 case GE:    print0(" <= "); break;
  477.                             }
  478.                             print_node(vars, preds->dest);
  479.                             return TRUE;
  480.  
  481.             case WAIT:      print0("$wait");
  482.                             print0("(");
  483.                             print_rpars(vars, preds->pars, IN);
  484.                             print0(")!");
  485.                             print_node(vars,  preds->dest);
  486.                             print0("[");
  487.                             print_vars(vars,  step);
  488.                             print0("] ");
  489.                             return TRUE;
  490.  
  491.             case POST:      print0("$post");
  492.                             print0("(");
  493.                             print_rpars(vars, preds->pars, IN);
  494.                             print0(")!");
  495.                             print_node(vars,  preds->dest);
  496.                             return TRUE;
  497.  
  498.             case SEND:      print1("&%d",     preds->moff);
  499.                             print0("[");
  500.                             print_rargs(preds->pars, IN);
  501.                             print0("]");
  502.                             print0("(");
  503.                             print_rpars(vars, preds->pars, IN);
  504.                             print0(")");
  505.                             print0("[");
  506.                             print_rargs(preds->pars, OUT);
  507.                             print0("]");
  508.                             print0(" ! ");
  509.                             print_node(vars,  preds->dest);
  510.  
  511.                             if (preds->next) {
  512.                                 print0(",\n\t");
  513.                                 print_preds(vars, step, preds->next, last);
  514.                             }
  515.                             print1(" :%d", len_pars(preds->pars, OUT));
  516.                             print0("(");
  517.                             print_pars(vars,  preds->pars, OUT);
  518.                             print0(")");
  519.                             return TRUE;
  520.  
  521.             default:        print1("&%d",     preds->moff);
  522.                             print1(":%d",     len_pars(preds->pars, IN));
  523.                             print1(":%d",     len_pars(preds->pars, OUT));
  524.                             print0("(");
  525.                             print_rpars(vars, preds->pars, IN);
  526.                             print0(")");
  527.  
  528.                             switch (preds->tag) {
  529.                                 case INVK:  print0(" ! ");
  530.                                             print_node(vars, preds->dest);
  531.                                             break;
  532.                                 case CALL:  if (preds->dest)
  533.                                                 print1(" ::%s", preds->dest);
  534.                             }
  535.                             print0("[");
  536.                             print_vars(vars, step);
  537.                             print0("] ");
  538.                             print0("(");
  539.                             print_pars(vars, preds->pars, OUT);
  540.                             print0(")");
  541.         }
  542.         return TRUE;
  543. }
  544.  
  545. int     print_clus(vars, step, clus, last)
  546. Var    *vars;
  547. int     step;
  548. Clu    *clus;
  549. Pred   *last;
  550. {
  551.         while (clus) {
  552.             Pred *preds = clus->pred;
  553.             print0("\t");
  554.             if (!print_preds(vars, step, preds, last))
  555.                 return HEAD;
  556.             step += NEXT;
  557.             clus = clus->next;
  558.             print0(clus && clus->pred != last ? ";\n" : "");
  559.         }
  560.         return step;
  561. }
  562.  
  563. void    print_rules(rules, kind)
  564. Rule   *rules;
  565. int     kind;
  566. {
  567.         int     moff = -1;
  568.  
  569.         for (; rules; rules = rules->next) {
  570.             Var  *vars = rules->vars;
  571.             Head *head = rules->head;
  572.             Clu  *body = rules->body;
  573.             Clu  *tail = rules->tail;
  574.             Pred *last = rules->last;
  575.             int   step = HEAD;
  576.  
  577.             if (moff != head->moff) {
  578.                 print1("&%d:", moff = head->moff);
  579.                 print1("%d:",  len_pars(head->pars, IN));
  580.                 print1("%d:",  len_pars(head->pars, OUT));
  581.                 print1("%d",   max_vars(rules, moff));
  582.                 if (in_rules(rules, moff)) {
  583.                     print0(" [");
  584.                     print_vars(vars, step);
  585.                     print0("]");
  586.                 }
  587.             }
  588.             if (last && (!tail && !islast(rules, moff)
  589.                      || !match_pars(head->pars, last->pars)))
  590.                 last = NUL;
  591.  
  592.             print0(islast(rules, moff) ? ";\n " : "\n ");
  593.             print0("(");
  594.             print_pars(vars, head->pars, IN);
  595.             print0(")");
  596.  
  597.             step = BODY;
  598.             if (body && body->pred != last) {
  599.                 print0(" :-\n");
  600.                 step = print_clus(vars, step, body, last);
  601.             }
  602.             if (tail && tail->pred != last && step != HEAD) {
  603.                 print0(" |-\n");
  604.                 step = print_clus(vars, step, tail, last);
  605.             }
  606.             print0("\n\t=> ");
  607.             if (!last && step != HEAD) {
  608.                 if (in_pars(head->pars, OUT)) {
  609.                     print0("[");
  610.                     print_vars(vars, step);
  611.                     print0("] ");
  612.                 }
  613.                 print0("(");
  614.                 print_rpars(vars, head->pars, OUT);
  615.                 print0(")");
  616.                 if (kind == AGENT && head->prot == PUBLIC)
  617.                     print0("*");
  618.             }
  619.             else if (last) print_last(vars, last);
  620.             print0(islast(rules, moff) ? ".\n" : ";");
  621.         }
  622. }
  623.  
  624. void    print_atts(atts)
  625. Att    *atts;
  626. {
  627.         Att    *as;
  628.  
  629.         for (as = atts; as;)
  630.             if (isword(as->type)) {
  631.                 print1("`%d", as->aoff);
  632.                 print_tag    (as->type);
  633.                 do  as = as->next;
  634.                 while (as && !isword(as->type));
  635.                 print0(as ? "," : "");
  636.             }
  637.             else as = as->next;
  638.         print0(";");
  639.  
  640.         for (as = atts; as;)
  641.             if (ispointer(as->type)) {
  642.                 print1("`%d", as->aoff);
  643.                 print_tag    (as->type);
  644.                 do  as = as->next;
  645.                 while (as && !ispointer(as->type));
  646.                 print0(as ? "," : "");
  647.             }
  648.             else as = as->next;
  649.         print0(";");
  650.  
  651.         for (as = atts; as;)
  652.             if (ismeta(as->type)) {
  653.                 print1("`%d", as->aoff);
  654.                 print_tag    (as->type);
  655.                 do  as = as->next;
  656.                 while (as && !ismeta(as->type));
  657.                 print0(as ? "," : "");
  658.             }
  659.             else as = as->next;
  660. }
  661.  
  662. void    print_goal(goal)
  663. Goal   *goal;
  664. {
  665.         Var    *vars = goal->vars;
  666.         int     s    = 1;
  667.  
  668.         for (; vars; vars = vars->next) {
  669.             vars->use  = LAST;
  670.             vars->voff = -++s;
  671.         }
  672.         print1("?- %d ", s - 1);
  673.         print_clus(goal->vars, BODY, goal->body, NUL);
  674.         print0(".\n");
  675. }
  676.  
  677. void    print_spec(spec)
  678. Spec   *spec;
  679. {
  680.         Gene *genes = spec->genes;
  681.  
  682.         spec->mark = TRUE;
  683.         if (spec->base)
  684.             print1("%s :: ", spec->base->name);
  685.         print1("%s:", spec->name);
  686.         print1("%d:", spec->size);
  687.         print1("%d",  Moff(spec->mets));
  688.  
  689.         if (genes) print0(" <");
  690.         while (genes) {
  691.             print1("`%d", genes->goff);
  692.             genes = genes->next;
  693.             print0(genes ? "," : ">");
  694.         }
  695.         print0("\n{");
  696.         print_atts(spec->atts);
  697.         print0("}\n");
  698. }
  699.  
  700. void    print_specs()
  701. {
  702.         Spec   *prev;
  703.         Spec   *next;
  704.  
  705.         for (prev = NUL; specs;) {
  706.             next = specs->next;
  707.             specs->next = prev;
  708.             prev = specs;
  709.             specs = next;
  710.         }
  711.         for (specs = prev; specs; specs = specs->next)
  712.             if (!specs->mark && !specs->mets) {
  713.                 print_spec(specs);
  714.                 print0("{}\n");
  715.             }
  716. }
  717.  
  718. void    print_imps()
  719. {
  720.         Imp    *prev;
  721.         Imp    *next;
  722.  
  723.         for (prev = NUL; imps;) {
  724.             next = imps->next;
  725.             imps->next = prev;
  726.             prev = imps;
  727.             imps = next;
  728.         }
  729.         for (imps = prev; imps; imps = imps->next) {
  730.             int   kind = isupper(*imps->name) ? AGENT : OBJECT;
  731.             print_spec(imps->spec);
  732.             print0("{\n");
  733.             if (imps->goal)
  734.                 print_goal(imps->goal);
  735.             print_rules(imps->rules, kind);
  736.             print0("}\n");
  737.         }
  738. }
  739.  
  740. void    print_classes(buf)
  741. char   *buf;
  742. {
  743.         ptr = buf;
  744.         print_imps();
  745.         print_specs();
  746. }
  747.  
  748. char   *print_globals(buf)
  749. char   *buf;
  750. {
  751.         Att    *atts = goal->atts;
  752.         Att    *prev;
  753.         Att    *next;
  754.  
  755.         ptr  = buf;
  756.         prev = NUL;
  757.         while (atts != Atts0) {
  758.             next = atts->next;
  759.             atts->next = prev;
  760.             prev = atts;
  761.             atts = next;
  762.         }
  763.         atts = prev;
  764.         while (atts) {
  765.             print1("%s ", atts->name);
  766.             print_type   (atts->type);
  767.             print0("\n");
  768.             atts = atts->next;
  769.         }
  770.         *ptr++ = '\0';
  771.         return ptr;
  772. }
  773.  
  774. char   *print_locals(buf)
  775. char   *buf;
  776. {
  777.         Var    *vars = goal->vars;
  778.         Var    *prev;
  779.         Var    *next;
  780.         int     vno = 0;
  781.  
  782.         ptr  = buf;
  783.         for (prev = NUL; vars; vno++) {
  784.             next = vars->next;
  785.             vars->next = prev;
  786.             prev = vars;
  787.             vars = next;
  788.         }
  789.         print1("%d\n", vno);
  790.         vars = prev;
  791.         prev = NUL;
  792.         while (vars) {
  793.             print1("%s ", vars->name);
  794.             print_tag    (vars->mint);
  795.             print0("\n");
  796.             next = vars->next;
  797.             vars->next = prev;
  798.             prev = vars;
  799.             vars = next;
  800.         }
  801.         return ++ptr;
  802. }
  803.  
  804. void    print_main(buf)
  805. char   *buf;
  806. {
  807.         ptr = buf;
  808.         print_goal(goal);
  809. }
  810.  
  811.